//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#ifndef RS_REFLECTION_ATTRIBUTE_HPP
#define RS_REFLECTION_ATTRIBUTE_HPP

#include "rs/Reflection/AttributeProperties.hpp"
#include "rs/Reflection/Types.hpp"
#include "rs/Portability.hpp"
#include <map>
#include <cstring>

namespace rs
{
    namespace reflection
    {           
        class Attribute
        {
            template< typename T > friend class ClassBuilder;
            
        public:
            
            Attribute();
            
            Attribute(Char8 const* name, Type const& type, UIntPtr offset);
            
            Attribute(Attribute const& other);
            
            Boolean Equals(Attribute const& other) const;
            
            Char8 const* GetName() const;
            
            Type const& GetType() const;
            
            UIntPtr GetOffset() const;
            
            AttributeProperties const& GetProperties() const;
            
        protected:
            
            void SetAttributesProperties(AttributeProperties const& properties);
            
        private:
            
            AttributeProperties metaProperties_;
            Char8 const* name_;
            UIntPtr offset_;
            Type type_;
        };
        
        
        inline Attribute::Attribute()
        : name_(0),
          offset_(0),
          type_(0) {
        }
        
        inline Attribute::Attribute(Char8 const* name, Type const& type, UIntPtr offset)
        : name_(name),
          offset_(offset),
          type_(type) {
        }
        
        inline Attribute::Attribute(Attribute const& other)
        : metaProperties_(other.metaProperties_),
          name_(other.name_),
          offset_(other.offset_),
          type_(other.type_) {
        }
        
        inline Boolean Attribute::Equals(Attribute const& other) const {
            return (offset_ == other.offset_) && (type_ == other.type_) && (std::strcmp(name_, other.name_) == 0 && (metaProperties_ == other.metaProperties_));
        }
        
        inline Char8 const* Attribute::GetName() const {
            return name_;
        }
        
        inline Type const& Attribute::GetType() const {
            return type_;
        }
        
        inline UIntPtr Attribute::GetOffset() const {
            return offset_;
        }
        
        inline AttributeProperties const& Attribute::GetProperties() const {
            return metaProperties_;
        }
        
        inline void Attribute::SetAttributesProperties(AttributeProperties const& properties) {
            metaProperties_ = properties;
        }
    }
}

#endif // RS_REFLECTION_ATTRIBUTE_HPP